/**
 * framebuffer.h
 * 
 * @author Zsolt Horváth 
 * @date   3. 4. 2011
 * 
 */

#ifndef FRAMEBUFFER_H_
#define FRAMEBUFFER_H_

#include <vector>

#include "texture.h"

#include <GL/glew.h>
#include <GL/glu.h>

using namespace std;

/**
 * Textures of framebuffer
 */
typedef struct TFrameBufferTexture {
    // Texture 
    Texture *texture;
    // unit use to bind texture
    GLenum unit;
} FramebufferTexture;

/**
 * OpenGL framebuffer
 * 
 * Automatically deletes texture instances
 */
class Framebuffer {
    
    public:
        /**
         * Constructor
         * 
         * @param GLenum target - framebuffer target 
         */
        Framebuffer (GLenum target);

        /**
         * Constructor
         * 
         * @param GLenum target - framebuffer target 
         * @param GLunit framebuffer - framebuffer
         */        
        Framebuffer (GLenum target, GLuint framebuffer);
        
        /**
         * Destructor
         */
        ~Framebuffer ();
        
        /**
         * Bind a framebuffer to a framebuffer target
         */
        void bind ();
        
        /**
         * Get target id of framebuffer
         */
        GLuint getID();
        
        /**
         * Attach a level of a texture object as a logical buffer 
         * to the currently bound framebuffer object
         */ 
        void addTexture2D(GLenum attachment, Texture *texture);
        void addTexture2D(GLenum attachment, Texture *texture, GLenum unit);
        
        /**
         * Specifies a list of color buffers to be drawn into
         * 
         * Defines an array of buffers into which outputs
         * from the fragment shader data will be written
         */
        void drawBuffers();
        
        /**
         * Bind framebuffers textures
         * This method is used by other framebuffers, those
         * requires to get image rendered into texture this
         * framebuffer's textures
         */
        void bindTextures ();
        
        /**
         * Resize frambuffer's textures
         */
        void resizeTextures (int width, int height);
    protected:
        
        /**
         * Specifies the target texture
         */
        GLuint id;
        
        /**
         * Specifies the framebuffer target        
         */
        GLenum target;
        
         /**
          * Generate framebuffer
          */
        void generate ();
        
        /**
         * Framebuffer attachments
         */
        vector<GLenum> attachments;
        
        /**
         * Textures of framebuffer for binding
         */
        vector<FramebufferTexture> textures;
        
        /**
         * Textures those must be resized
         */
        vector<Texture *> texturesResize;
        
        
};

#endif /* FRAMEBUFFER_H_ */